package com.servers.threads;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.dao.DepartmentDao;
import com.dao.PersonDao;
import com.dao.impl.DepartmentDaoImpl;
import com.dao.impl.PersonDaoImpl;
import com.po.Department;
import com.po.Person;
import com.servers.ServersForDatabase;

public class DatabaseQueryforUser implements Runnable {

	private Socket sk;
	private Map<String, Person> mapPerson = new HashMap<String, Person>();
	static Person tmperson = new Person("aa", null, null, 0, 0);

	public DatabaseQueryforUser(Socket sk, Map<String, Person> mapPerson) {
		super();
		this.sk = sk;
		this.mapPerson = mapPerson;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			OutputStream outputStream = sk.getOutputStream();
			InputStream in = sk.getInputStream();
			BufferedReader reader = new BufferedReader(new InputStreamReader(in));
			String input = "Hey";
			while (true) {
				outputStream.write("Please input your Username and Password.(like:username/password)\n".getBytes());
				input = reader.readLine();
				if (Login(input))
					break;
				outputStream.write("The user name or password error\n".getBytes());
//				outputStream.write("Finish!\n".getBytes());   //bart did
			}
			Date date = new Date();
			tmperson.setLogin_time(date);
			tmperson.setIp(sk.getLocalAddress().getHostAddress());
			mapPerson.put(tmperson.getIp(), tmperson);
			outputStream.write("Login!\n".getBytes());
//			outputStream.write("Finish!\n".getBytes());   //bart did
			String s = "";
			while (true) {
				outputStream.write("Please enter your request\n".getBytes());
				input = reader.readLine();
				String seletor = input.substring(0, 4);
				seletor = seletor.trim();
				String data = input.substring(4);
				switch (seletor) {
				case "A-P":
					s = addPerson(data);
					break;
				case "A-D":
					s = addDepartment(data);
					break;
				case "U-P":
					s = updatePerson(data);
					break;
				case "U-D":
					s = updateDepartment(data);
					break;
				case "D-P":
					s = deletePerson(data);
					break;
				case "D-D":
					s = deleteDepartment(data);
					break;
				case "L-PA":
					s = queryPerson();
					break;
				case "L-DA":
					s = queryDepartment();
					break;
				case "L-PD":
					s = queryPersonWithDepartmentId(data);
					break;
				case "Quit":
					s = "Quit";
					break;
				default:
					s = "Undefined requst!";
					break;
				}
				if (s.equals("Quit"))
					break;
				outputStream.write((s + "\n").getBytes());
				outputStream.write("Finish!\n".getBytes());
//				if (!ServersForDatabase.isOpen()) {
//					break;
//				}
			}
			outputStream.write((s + "\n").getBytes());
			outputStream.write("Finish!\n".getBytes());
			outputStream.close();
			mapPerson.remove(tmperson.getIp());
			sk.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// 添加Person
	private String addPerson(String data) {
		String[] temp = data.split(",");
		Map<String, String> map = new HashMap<String, String>();
		for (String string : temp) {
			string = string.trim();
			if (!string.contains(":")) {
				return "Command ERROR!Miss ':' with elements";
			}
			String[] sub = string.split(":");
			if (sub.length < 2) {
				return "Command ERROR!Miss values after ':'";
			}
			sub[0] = sub[0].trim();
			sub[0] = sub[0].toLowerCase();
			sub[1] = sub[1].trim();
			map.put(sub[0], sub[1]);
		}
		if (!(map.get("birthday") == null)) {
			if (!(isDate(map.get("birthday")))) {
				return "The birthday format should be YYYY-MM-DD";
			}
		}
		if (!(map.get("pname") == null)) {
			if (!(isName(map.get("pname")))) {
				return "The pname should less than 15 letter";
			}
		}
		else
			return "The pname should not be null";
		if (!(map.get("did") == null)) {
			if (!(isNum(map.get("did")))) {
				return "The did(departmentid) should be num";
			}
		} else
			return "The did(departmentid) should not be null";
		if (!(map.get("tel") == null)) {
			if (!(isTel(map.get("tel")))) {
				return "The tel should be 11 digits";
			}
		}
		if (!(map.get("salary") == null)) {
			if (!(isNum(map.get("salary")))) {
				return "The salary should be num in 5";
			}
		} else
			map.put("salary", "0");
		DepartmentDao departmentDao = new DepartmentDaoImpl();
		Department department = departmentDao.loadDepartment(Integer.parseInt(map.get("did")));
		if (department == null) {
			return "The department of did could not find";
		}
		PersonDao d = new PersonDaoImpl();
		Person p = new Person(map.get("pname"), map.get("birthday"), map.get("tel"), Integer.parseInt(map.get("did")),
				Integer.parseInt(map.get("salary")));
		d.addPerson(p);
		return "Succeed insert in table Person!";
	}

	// 添加部门
	private String addDepartment(String data) {
		String[] temp = data.split(",");
		Map<String, String> map = new HashMap<String, String>();
		for (String string : temp) {
			string = string.trim();
			if (!string.contains(":")) {
				return "Command ERROR!Miss ':' with elements";
			}
			String[] sub = string.split(":");
			if (sub.length < 2) {
				return "Command ERROR!Miss values after ':'";
			}
			sub[0] = sub[0].trim();
			sub[0] = sub[0].toLowerCase();
			sub[1] = sub[1].trim();
			map.put(sub[0], sub[1]);
		}
		if (!(map.get("dname") == null)) {
			if (!(isLongName(map.get("dname")))) {
				return "The dname should less than 20 letter";
			}
		}
		else
			return "The dname should not be null";
		if (!(map.get("city") == null)) {
			if (!(isLongName(map.get("city")))) {
				return "The city should less than 20 letter";
			}
		}
		DepartmentDao departmentDao = new DepartmentDaoImpl();
		Department d = new Department(map.get("dname"), map.get("city"));
		departmentDao.addDepartment(d);
		return "Succeed insert in table department!";
	}

	// 更新Person
	private String updatePerson(String data) {
		String[] temp = data.split(",");
		Map<String, String> map = new HashMap<String, String>();
		for (String string : temp) {
			string = string.trim();
			if (!string.contains(":")) {
				return "Command ERROR!Miss ':' with elements";
			}
			String[] sub = string.split(":");
			if (sub.length < 2) {
				return "Command ERROR!Miss values after ':'";
			}
			sub[0] = sub[0].trim();
			sub[0] = sub[0].toLowerCase();
			sub[1] = sub[1].trim();
			map.put(sub[0], sub[1]);
		}
		if (!(map.get("id") == null)) {
			if (!(isNum(map.get("id")))) {
				return "The id should be num";
			}
		} else
			return "The id should not be null";
		if (!(map.get("birthday") == null)) {
			if (!(isDate(map.get("birthday")))) {
				return "The birthday format should be yyyy-MM-DD";
			}
		}
		if (!(map.get("pname") == null)) {
			if (!(isName(map.get("pname")))) {
				return "The pname should less than 15 letter";
			}
		}
		else
			return "The pname should not be null";
		if (!(map.get("did") == null)) {
			if (!(isNum(map.get("did")))) {
				return "The did(departmentid) should be num";
			}
		} else
			return "The did(departmentid) should not be null";
		if (!(map.get("tel") == null)) {
			if (!(isTel(map.get("tel")))) {
				return "The tel should be 11 digits";
			}
		}
		if (!(map.get("salary") == null)) {
			if (!(isNum(map.get("salary")))) {
				return "The salary should be num in 5";
			}
		} else
			map.put("salary", "0");
		PersonDao d = new PersonDaoImpl();
		Person sPerson = d.loadPerson(Integer.parseInt(map.get("id")));
		if (sPerson == null)
			return "The Person of id could not find";

		DepartmentDao departmentDao = new DepartmentDaoImpl();
		Department department = departmentDao.loadDepartment(Integer.parseInt(map.get("did")));
		if (department == null) {
			return "The department of did could not find";
		}

		Person p = new Person(map.get("pname"), map.get("birthday"), map.get("tel"), Integer.parseInt(map.get("did")),
				Integer.parseInt(map.get("salary")));
		p.setId(Integer.parseInt(map.get("id")));
		d.updatePerson(p);
		return "Succeed update table Person!";
	}

	// 更新部门
	private String updateDepartment(String data) {
		String[] temp = data.split(",");
		Map<String, String> map = new HashMap<String, String>();
		for (String string : temp) {
			string = string.trim();
			if (!string.contains(":")) {
				return "Command ERROR!Miss ':' with elements";
			}
			String[] sub = string.split(":");
			if (sub.length < 2) {
				return "Command ERROR!Miss values after ':'";
			}
			sub[0] = sub[0].trim();
			sub[0] = sub[0].toLowerCase();
			sub[1] = sub[1].trim();
			map.put(sub[0], sub[1]);
		}
		if (!(map.get("did") == null)) {
			if (!(isNum(map.get("did")))) {
				return "The did should be num";
			}
		} else
			return "The did should not be null";
		if (!(map.get("dname") == null)) {
			if (!(isLongName(map.get("dname")))) {
				return "The dname should less than 20 letter";
			}
		}
		else
			return "The dname should not be null";
		if (!(map.get("city") == null)) {
			if (!(isLongName(map.get("city")))) {
				return "The city should less than 20 letter";
			}
		}
		DepartmentDao departmentDao = new DepartmentDaoImpl();
		Department department = departmentDao.loadDepartment(Integer.parseInt(map.get("did")));
		if (department == null) {
			return "The department of did could not find";
		}
		Department d = new Department(map.get("dname"), map.get("city"));
		d.setDid(Integer.parseInt(map.get("did")));
		departmentDao.updateDepartment(d);
		return "Succeed update table department!";
	}

	// 删除Person
	private String deletePerson(String data) {
		Map<String, String> map = new HashMap<String, String>();
		String string = data.trim();
		if (!string.contains(":")) {
			return "Command ERROR!Miss ':' with elements";
		}
		String[] sub = string.split(":");
		if (sub.length < 2) {
			return "Command ERROR!Miss values after ':'";
		}
		sub[0] = sub[0].trim();
		sub[0] = sub[0].toLowerCase();
		sub[1] = sub[1].trim();
		map.put(sub[0], sub[1]);
		if (!(map.get("id") == null)) {
			if (!(isNum(map.get("id")))) {
				return "The id should be num";
			}
		} else
			return "The id should not be null";

		PersonDao d = new PersonDaoImpl();
		Person sPerson = d.loadPerson(Integer.parseInt(map.get("id")));
		if (sPerson == null)
			return "The Person of id could not find";
		d.deletePerson(Integer.parseInt(map.get("id")));

		return "Succeed delete from table Person!";

	}

	// 删除Department
	private String deleteDepartment(String data) {
		Map<String, String> map = new HashMap<String, String>();
		String string = data.trim();
		if (!string.contains(":")) {
			return "Command ERROR!Miss ':' with elements";
		}
		String[] sub = string.split(":");
		if (sub.length < 2) {
			return "Command ERROR!Miss values after ':'";
		}
		sub[0] = sub[0].trim();
		sub[0] = sub[0].toLowerCase();
		sub[1] = sub[1].trim();
		map.put(sub[0], sub[1]);
		if (!(map.get("did") == null)) {
			if (!(isNum(map.get("did")))) {
				return "The did should be num";
			}
		} else
			return "The did should not be null";
		DepartmentDao departmentDao = new DepartmentDaoImpl();
		Department department = departmentDao.loadDepartment(Integer.parseInt(map.get("did")));
		if (department == null) {
			return "The department of did could not find";
		}
		departmentDao.deleteDepartment(Integer.parseInt(map.get("did")));
		PersonDao d = new PersonDaoImpl();
		d.deletePersonWithDid(Integer.parseInt(map.get("did")));
		return "Succeed delete from table Department!";
	}

	// 查询Person
	private String queryPerson() {
		PersonDao personDao = new PersonDaoImpl();
		StringBuilder data = new StringBuilder();
		List<Person> ds = personDao.showAllPerson();
		data.append("id\t pname\t birthday\t tel\t\t did\t salary \n");
		for (Person person : ds) {
			data.append(person.getId() + "\t " + person.getPname() + "\t " + person.getBirthday() + "\t "
					+ person.getTel() + "\t " + person.getDid() + "\t " + person.getSalary() + "\n");
		}
		return data.toString();
	}

	// 查询Department
	private String queryDepartment() {
		DepartmentDao departDao = new DepartmentDaoImpl();
		StringBuilder data = new StringBuilder();
		List<Department> ds = departDao.showAllDepartment();
		data.append("did\t dname\t city \n");
		for (Department department : ds) {
			data.append(department.getDid() + "\t " + department.getDname() + "\t " + department.getCity() + "\n");
		}
		return data.toString();
	}

	// 通过Department查询Person
	private String queryPersonWithDepartmentId(String data) {
		Map<String, String> map = new HashMap<String, String>();
		String string = data.trim();
		if (!string.contains(":")) {
			return "Command ERROR!Miss ':' with elements";
		}
		String[] sub = string.split(":");
		if (sub.length < 2) {
			return "Command ERROR!Miss values after ':'";
		}
		sub[0] = sub[0].trim();
		sub[0] = sub[0].toLowerCase();
		sub[1] = sub[1].trim();
		map.put(sub[0], sub[1]);
		if (!(map.get("did") == null)) {
			if (!(isNum(map.get("did")))) {
				return "The did should be num";
			}
		} else
			return "The did should not be null";

		DepartmentDao departmentDao = new DepartmentDaoImpl();
		Department department = departmentDao.loadDepartment(Integer.parseInt(map.get("did")));
		if (department == null) {
			return "The department of did could not find";
		}
		PersonDao personDao = new PersonDaoImpl();

		String newdata = personDao.showPersonwithDepartment(Integer.parseInt(map.get("did")));

		return newdata;
	}

	private boolean Login(String s) {
		String[] strings = s.split("/");
		strings[0].trim();
		PersonDao personDao = new PersonDaoImpl();
		tmperson = personDao.loadPersonWithname(strings[0]);
		if (tmperson!=null)
			return true;
		return false;
	}

	// 日期的正则表达式匹配
	private boolean isDate(String s) {
		Pattern pattern = Pattern.compile("^(19|20)[0-9][0-9]-(0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-9]|3[01])$");
		Matcher matcher = pattern.matcher(s);
		if (matcher.find())
			return true;
		return false;
	}

	// 工资与部门正则表达式
	private boolean isNum(String s) {
		Pattern pattern = Pattern.compile("^[0-9]{1,5}$");
		Matcher matcher = pattern.matcher(s);
		if (matcher.find()) {
			return true;
		}
		return false;
	}

	// 电话正则表达式
	private boolean isTel(String s) {
		Pattern pattern = Pattern.compile("^(\\d){11}$");
		Matcher matcher = pattern.matcher(s);
		if (matcher.find())
			return true;
		return false;
	}

	// 名字正则表达式
	private boolean isName(String s) {
		Pattern pattern = Pattern.compile("^[a-zA-Z0-9]{0,15}$");
		Matcher matcher = pattern.matcher(s);
		if (matcher.find()) {
			return true;
		}
		return false;
	}

	// 部门和城市正则
	private boolean isLongName(String s) {
		Pattern pattern = Pattern.compile("^[a-zA-Z0-9]{0,20}$");
		Matcher matcher = pattern.matcher(s);
		if (matcher.find()) {
			return true;
		}
		return false;
	}

}
